var UUID = require('uuid/v1');
var mathNum = function (min, max) {
    return Math.random() * (max - min + 1) + min
};

var User = function (name, res) {
    this.id = UUID();
    this.name = name;
    this.res = res;
};

var KingsConfig = [{
    name: 'attack',
    fun: function (event, user) {
        event.hit(user, 1);
    }
}, {
    name: 'attack+',
    fun: function (event, user) {
        event.hit(user, 2);
    }
}, {
    name: 'attack++',
    fun: function (event, user) {
        event.hit(user, 5);
    }
}, {
    name: 'back-his',
    fun: function (event, user) {
        var other = user == 'player1' ? 'player2' : 'player1';
        event.backToList(other);
    }
}, {
    name: 'back-me',
    fun: function (event, user) {
        event.backToList(user);
    }
}, {
    name: 'change',
    fun: function (event) {
        event.exchange();
    }
}, {
    name: 'fire',
    fun: function (event) {
        event.exchange();
    }
}, {
    name: 'fire+',
    fun: function (event) {
        event.exchange();
    }
}, {
    name: 'fire++',
    fun: function (event) {
        event.exchange();
    }
}, {
    name: 'shield',
    fun: function (event) {
        event.exchange();
    }
}, {
    name: 'shield+',
    fun: function (event) {
        event.exchange();
    }
}, {
    name: 'shield++',
    fun: function (event) {
        event.exchange();
    }
}, {
    name: 'take-2',
    fun: function (event) {
        event.exchange();
    }
}, {
    name: 'take-3',
    fun: function (event) {
        event.exchange();
    }
}, {
    name: 'take-4',
    fun: function (event) {
        event.exchange();
    }
}, {
    name: 'take-5',
    fun: function (event) {
        event.exchange();
    }
}, {
    name: 'take-6',
    fun: function (event) {
        event.exchange();
    }
}, {
    name: 'take-7',
    fun: function (event) {
        event.exchange();
    }
}, {
    name: 'take-com',
    fun: function (event) {
        event.exchange();
    }
}, {
    name: 'play24',
    fun: function (event) {
        event.exchange();
    }
}, {
    name: 'play27',
    fun: function (event) {
        event.exchange();
    }
}]



User.prototype = {
    constructor: this,
    // 向人员发送消息
    send: function (data, type) {
        if (type) {
            this.res.write("event: " + type + "\n");
        };
        this.res.write("data:" + JSON.stringify(data) + "\n\n");
    },
    // 获取人员信息
    get: function () {
        return {
            id: this.id,
            name: this.name
        }
    }
};
var Fight = function (room) {
    this.libs = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
    this.sortLibs();
    this.room = room;
    this.turn = Math.round(Math.random()) ? 'player1' : 'player2';
    // start  
    // 0 准备中
    // 1 已准备
    // 2 回合中
    // 3 准备下一回合
    // 4 准备结算
    // 5 游戏结束

    this.player1 = {
        start: 0,
        hit: 0,
        health: 5,
        cards: [],
        kings: [],
        user: null,
    };
    this.player2 = {
        start: 0,
        hit: 0,
        health: 5,
        cards: [],
        kings: [],
        user: null,
    };
    this.kings = {};
    this.start = 0;
    this.condition = 21;
};
Fight.prototype = {
    constructor: this,
    // 洗牌
    sortLibs: function () {
        this.libs.sort(function (a, b) {
            return Math.random() > .5 ? -1 : 1;
        });
    },
    // 准备
    userReady: function (id, callback) {
        var OtherUser = null;
        var user = null;
        if ((this.player1.user != null) && (this.player1.user == id)) {
            user = this.player1;
            OtherUser = this.player2.user;
        } else if ((this.player2.user != null) && (this.player2.user == id)) {
            OtherUser = this.player1.user;
            user = this.player2;
        };
        user.start = 1;
        if (otherPeople) {
            otherPeople.send(id, 'ready');
        };

        this.checkAllReady();
    },
    // 检查准备状态
    checkReady: function () {
        if ((this.player1.start == 1) && (this.player2.start == 1)) {
            this.status = 1;
            this.room.send('start', 'gameStart', function () { });
            this.changeTurn();
        };
    },
    // 交换牌权
    changeTurn: function () {
        this.turn = this.turn == 'player1' ? 'player2' : 'player1';
        this.room.send(this[this.turn].user.id, 'turn', function () { });
    },
    // 牌库检索
    indexOf: function (num) {
        var index = false;
        for (let i = 0; i < this.libs.length; i++) {
            const element = this.libs[i];
            if (element == num) {
                index = i;
                break;
            };
        };
        return index;
    },
    // 手牌求和
    sum: function (user) {
        var _array = this[user].cards;
        var ans = 0;
        for (let i = 0; i < _array.length; i++) {
            const element = _array[i];
            ans += element;
        };
        return ans;
    },
    // 发牌
    deal: function (user, number) {
        // 抽排方法
        var card = null;
        if (number == 'perfect') {
            // 完美抽
            var sum = this.sum(user);
            var want = this.condition - sum;
            function haveNum(want) {
                var index = this.indexOf(want);
                if (index) {
                    return {
                        index: index,
                        card: want
                    };
                } else {
                    if (want == 0) {
                        return false;
                    } else {
                        haveNum((want - 1));
                    }
                };
            };
            var _card = haveNum(want);
            if (_card) {
                this.libs.splice(_card.index, 1);
                card = _card.card;
            };
            // this.condition
        } else if (number) {
            // 指定抽
            var index = this.indexOf(number);
            if (index) {
                this.libs.splice(index, 1);
                card = number;
            };
        } else {
            // 随机抽
            if (this.libs.length > 0) {
                card = this.libs.pop();
            };
        };
        var other = user == 'player1' ? 'player2' : 'player1';
        if (card) {
            this[user].user.send(card, 'mainCard', function () { });
            if (this[user].cards.length == 0) {
                this[other].user.send(0, 'rivalCard', function () { });
            } else {
                this[other].user.send(card, 'rivalCard', function () { });
            };
        };
    },
    // 收牌 最后一张牌
    backCard: function (user) {
        var card = this[user].cards.pop();
        this[user].user.send('', 'mainBackCard', function () { });
        this[other].user.send('', 'rivalBackCard', function () { });
    },
    // 退回到牌组
    backToList: function (user) {
        if (this[user].cards.length > 2) {
            var num = this.backCard(user);
            this.libs.push(num);
            this.sortLibs();
            return true;
        } else {
            return false;
        };
    },
    // 交换手牌
    exchange: function () {
        var player1LastCard = this.backCard('player1');
        var player2LastCard = this.backCard('player2');
        this.deal('player1', player2LastCard);
        this.deal('player2', player1LastCard);
    },
    // 攻击及生命计算
    hit: function (user, number) {
        this[user].hit += number;
        var _hit = 0;
        if (this[user].hit > 5) {
            _hit = 5;
        } else if (this[user].hit < 0) {
            _hit = 0;
        };
        var other = user == 'player1' ? 'player2' : 'player1';
        if (_hit) {
            this[user].user.send(_hit, 'mainHit', function () { });
            this[other].user.send(_hit, 'rivalHit', function () { });
        };
    },
    // 生命结算
    health: function (user) {
        var _health = this[user].health;
        if (this[user].hit >= 0) {
            _health -= this[user].hit;
            if (_health <= 0) {
                _health = 0;
            };
        };
        this[user].health = _health;
        this[user].hit = 0;
        var other = user == 'player1' ? 'player2' : 'player1';
        if (_health) {
            this[user].user.send(_health, 'mainHealth', function () { });
            this[other].user.send(_health, 'rivalHealth', function () { });
            this[user].user.send(0, 'mainHit', function () { });
            this[other].user.send(0, 'rivalHit', function () { });
            this.GameEnd();
        };
    },
    // 单局结算
    roundEnd: function () {
        var player1CardSum = this.sum('player1');
        var player2CardSum = this.sum('player2');
        var condition = this.condition;
        var winer = null;

        if (player1CardSum == player2CardSum) {
            winer = 'draw';
        } else if (player1CardSum > condition && player2CardSum > condition) {
            if (player1CardSum > player2CardSum) {
                winer = 'player2';
            } else {
                winer = 'player1';
            }
        } else if (player1CardSum <= condition && player2CardSum <= condition) {
            if (player1CardSum > player2CardSum) {
                winer = 'player1';
            } else {
                winer = 'player2';
            }
        } else if (player1CardSum <= condition && player2CardSum > condition) {
            winer = 'player1';
        } else if (player1CardSum > condition && player2CardSum <= condition) {
            winer = 'player2';
        };
        if (winer) {
            switch (winer) {
                case 'draw':
                    this.player1.user.send({
                        type: 'draw',
                        backCard: this.player2.cards[0],
                    }, 'roundEnd', function () { });
                    this.player2.user.send({
                        type: 'draw',
                        backCard: this.player1.cards[0],
                    }, 'roundEnd', function () { });
                    break;
                case 'player1':
                    this.player1.user.send({
                        type: 'win',
                        backCard: this.player2.cards[0],
                    }, 'roundEnd', function () { });
                    this.player2.user.send({
                        type: 'lose',
                        backCard: this.player1.cards[0],
                    }, 'roundEnd', function () { });
                    this.health();
                    break;
                case 'player2':
                    this.player1.user.send({
                        type: 'lose',
                        backCard: this.player2.cards[0],
                    }, 'roundEnd', function () { });
                    this.health();
                    this.player2.user.send({
                        type: 'win',
                        backCard: this.player1.cards[0],
                    }, 'roundEnd', function () { });
                    break;
            }
        };
    },
    // 全局结算
    GameEnd: function () {
        var user = 'player1';
        var other = user == 'player1' ? 'player2' : 'player1';
        if (this[user].health == 0) {
            this.player1.user.send('lose', 'GameEnd', function () { });
            this.player2.user.send('win', 'GameEnd', function () { });
        } else if (this[other].health == 0) {
            this.player2.user.send('lose', 'GameEnd', function () { });
            this.player1.user.send('win', 'GameEnd', function () { });
        };
    },
    // 王牌创建
    creatKings: function (user) {

    },
    // 王牌分发
    // 王牌使用
};
var Room = function () {
    this.id = UUID();
    this.name = name;
    this.player1 = null;
    this.player2 = null;
};
Room.prototype = {
    constructor: this,
    // 向房间中人员发送消息
    send: function (data, type, callback) {
        if (this.player1 != null) {
            this.player1.send(data, type);
        };
        if (this.player2 != null) {
            this.player2.send(data, type);
        };
        if (this.player1 === null && this.player2 === null) {
            callback('发送失败');
        } else {
            callback(null);
        };
    },
    // 删除房间中人员
    remove: function (userId, callback) {
        if (this.player1 && this.player1.getId() == userId) {
            this.player1 = null;
            // this.fight.leaveFight('red');
            callback(false);
        } else if (this.player2 && this.player2.getId() === userId) {
            this.player2 = null;
            // this.fight.leaveFight('greed');
            callback(false);
        } else {
            callback('未找到人员');
        }
    },
    // 向房间中添加人员
    set: function (user, callback) {
        if (this.player1 === null) {
            this.player1 = user;
            callback(false);
        } else if (this.player2 === null) {
            this.player2 = user;
            callback(false);
        } else {
            callback('房间已满');
        }
    },
    // 获取房间信息
    get: function () {
        var data = {};
        data.name = this.name;
        data.id = this.id;
        data.player1 = this.player1 ? this.player1.get() : null;
        data.player2 = this.player2 ? this.player2.get() : null;
        return data
    }
};

var Game = function () {
    this.users = {};
    this.usersLength = 0;
    this.rooms = {};
    this.roomsLength = 0;
    var _this = this;

    this.user = {
        // 查找用户
        find: function (userId) {
            if (_this.users.hasOwnProperty(userId)) {
                return _this.users[userId];
            } else {
                return false;
            };
        },
        // 创建用户
        creat: function (name, res) {
            var user = new User(name, res);
            var userId = user.id;
            _this.users[userId] = user;
            _this.usersLength++;
            _this.groupSend(_this.usersLength, 'userNum');
            return user;
        },
        // 删除用户
        delete: function (userId, callback) {
            var user = _this.user.find(userId);
            if (user) {
                var room = _this.room.find(user.room);
                if (room) {
                    _this.leaveRoom(user.room, user.id, function (error) { });
                };
                user = null;
                delete _this.users[userId];
                _this.usersLength--;
                _this.groupSend(_this.usersLength, 'userNum');
                callback(false);
            } else {
                callback('未找到玩家');
            }
        },
        length: function () {
            return _this.usersLength;
        }
    };
    this.room = {
        // 创建房间
        creat: function (name) {
            var room = new Room(name);
            var roomId = room.id;
            _this.rooms[roomId] = room;
            _this.roomsLength++;
            _this.groupSend(JSON.stringify(room.get()), 'creatRoom');
            _this.groupSend(_this.roomsLength, 'roomNum');
            return room;
        },
        // 删除房间
        delete: function (roomId, callback) {
            var room = _this.room.find(roomId);
            if (room) {
                room = null
                delete _this.rooms[roomId];
                _this.roomsLength--;
                _this.groupSend(_this.roomsLength, 'roomNum');
                callback(false);
            } else {
                callback('未找到玩家');
            }
        },
        // 查找房间
        find: function (roomId) {
            if (_this.rooms.hasOwnProperty(roomId)) {
                var room = _this.rooms[roomId];
                return room;
            } else {
                return false;
            };
        },
        length: function () {
            return _this.roomsLength;
        }
    }
};
Game.prototype = {
    constructor: this,
    // 群发
    groupSend: function (data, type) {
        for (var key in this.users) {
            if (this.users.hasOwnProperty(key)) {
                var user = this.users[key];
                user.send(data, type);
            }
        };
    },
    // 单发
    singleSend: function (userId, data, type) {
        var user = this.user.find(userId);
        user.send(data, type);
    },
    // 按房间发送
    roomSend: function (roomId, data, type) {
        var room = this.room.find(roomId);
        room.send(data, type, function () { });
    },
    // 加入房间
    joinRoom: function (roomId, userId, callback) {
        var room = this.room.find(roomId);
        var user = this.user.find(userId);
        var _this = this;
        if (room && user) {
            room.set(user, function (error) {
                if (error) {
                    callback(error);
                } else {
                    callback(false);
                    _this.groupSend(JSON.stringify(user.get()), 'joinRoom');
                    room.send('玩家"' + user.name + '"加入房间', 'gameInterfaceSystemMessage', function (error) {
                        console.log('error');
                    });
                }
            });
        } else {
            callback('发生了一项错误');
        }
    },
    // 离开房间
    leaveRoom: function (roomId, userId, callback) {
        var room = this.room.find(roomId);
        var user = this.user.find(userId);
        var _this = this;
        if (room) {
            room.remove(userId, function (error) {
                if (error) {
                    callback(error);
                } else {
                    callback(false);
                    _this.groupSend(JSON.stringify(user.get()), 'leaveRoom');
                    room.send('玩家"' + user.name + '"离开了房间', 'gameInterfaceSystemMessage', function (error) {
                        console.log('error');
                    });
                };
            });
        } else {
            callback('发生了一项错误');
        };
        this.clearRooms();
    },
    //获取房间列表
    getRoomList: function () {
        var data = [];
        for (var key in this.rooms) {
            if (this.rooms.hasOwnProperty(key)) {
                var room = this.rooms[key];
                data.push(room.get());
            }
        }
        return data;
    },
    clearRooms: function () {
        var _array = [];
        for (var key in this.rooms) {
            if (this.rooms.hasOwnProperty(key)) {
                var room = this.rooms[key];
                if (room.player1) {
                    var player1 = this.user.find(room.player1.id);
                    if (!player1) {
                        room.player1 = null;
                    };
                };
                if (room.player2) {
                    var player2 = this.user.find(room.player2.id);
                    if (!player2) {
                        room.player2 = null;
                    };
                };
                if (room.player1 === null && room.player2 === null) {
                    _array.push(key);
                };
            }
        };
        for (var i = 0; i < _array.length; i++) {
            var id = _array[i];
            this.groupSend(id, 'deleteRoom');
            this.room.delete(id, function (error) {
                console.log(error)
            });
        };
    }
};


module.exports = function () {
    return new Game();
};